home *** CD-ROM | disk | FTP | other *** search
- //--------------------------------------------------------------------------
- //
- // Copyright (c) 2002, Colin Granville
- //
- // All rights reserved.
- //
- // Redistribution and use in source and binary forms, with or
- // without modification, are permitted provided that the following
- // conditions are met:
- //
- // * Redistributions of source code must retain the above copyright
- // notice, this list of conditions and the following disclaimer.
- //
- // * Redistributions in binary form must reproduce the above
- // copyright notice, this list of conditions and the following
- // disclaimer in the documentation and/or other materials
- // provided with the distribution.
- //
- // * The name Colin Granville may not be used to endorse or promote
- // products derived from this software without specific prior
- // written permission.
- //
- // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- // OF THE POSSIBILITY OF SUCH DAMAGE.
- //
- //--------------------------------------------------------------------------
-
- #include "Find.h"
- #include "DocView.h"
- #include "GuiWindow.h"
- #include "GuiGadget.h"
- #include "GuiTargets.h"
- #include "TextOutputDev.h"
- #include "GfxState.h"
- #include "UserEvents.h"
- #include "Document.h"
- #include "guilib:gfx.h"
- #include "strstream.h"
-
- class TextOutputDevice : public TextOutputDev
- {
- public:
- TextOutputDevice();
- virtual ~TextOutputDevice() {};
-
- double getHeight() {return height;}
- virtual void startPage(int pageNum, GfxState *state);
- private:
- double height;
- };
-
- //*************************************************************************
-
- TextOutputDevice::TextOutputDevice()
- : TextOutputDev(0,0,0,0),
- height(0)
- {
- }
-
- //*************************************************************************
-
- void TextOutputDevice::startPage(int pageNum, GfxState *state)
- {
- setDefaultCTM(state->getCTM());
- GuiBBox bounds;
- cvtUserToDev(state->getX1(),state->getY1(),&bounds.xmin,&bounds.ymin);
- cvtUserToDev(state->getX2(),state->getY2(),&bounds.xmax,&bounds.ymax);
- height=(double)(bounds.ymin-bounds.ymax);
- TextOutputDev::startPage(pageNum,state);
- }
-
- //*************************************************************************
- //*************************************************************************
- //*************************************************************************
-
- class Find
- {
- public:
- Find();
- ~Find();
-
- void aboutToBeShown(DocView& view);
- void viewClosed(DocView& view);
-
- private:
- GuiWindow window;
- GuiWritableField text;
- GuiOptionButton fromStart;
- GuiButton notFound;
-
- GuiWindow nextWindow;
- GuiButton nextStatus;
- GuiActionButton nextButton;
-
- DocView* view;
- TextOutputDevice outDev;
- int page;
- string searchString;
- bool top;
- double fromx,fromy;
-
- void showPageStatus();
-
- GUI_DECLARE_EVENT_TARGETS(Find);
-
- GuiNullTarget nullEventTarget;
- void nullEvent();
-
- GuiNullTarget nextHiddenTarget;
- void nextHidden();
-
- GuiToolboxTarget doFindTarget;
- Claim doFind(GuiToolboxEvent&,const GuiIdBlock&);
-
- GuiToolboxTarget findNextTarget;
- Claim findNext(GuiToolboxEvent&,const GuiIdBlock&);
-
- };
-
- //*************************************************************************
-
- Find::Find()
- : window("Find"),
- text(window,1),
- fromStart(window,2),
- notFound(window,5),
- nextWindow("FindNext"),
- nextStatus(nextWindow,5),
- nextButton(nextWindow,2),
- view(0),
- doFindTarget(&window,User_Find,this,Find::doFind),
- findNextTarget(&nextWindow,User_FindNext,this,Find::findNext)
- {
- }
-
- //*************************************************************************
-
- Find::~Find() {}
-
- //*************************************************************************
-
- void Find::aboutToBeShown(DocView& v)
- {
- view=&v;
- notFound.setValue("");
- fromStart.set(0);
- }
-
- //*************************************************************************
-
- void Find::viewClosed(DocView& v)
- {
- if (&v==view)
- {
- view=0;
- window.hide();
- nextWindow.hide();
- }
- }
-
- //*************************************************************************
-
- Claim Find::doFind(GuiToolboxEvent&,const GuiIdBlock&)
- {
- searchString=text.getValue();
- if (searchString.size()==0) return CLAIM;
-
- page=(fromStart.isOn()? 1 : view->getPage());
- nullEventTarget(this,Find::nullEvent);
- nextHiddenTarget(this,Find::nextHidden);
- nextWindow.showAsMenuCentred(window,&window);
- nextButton.fade(1);
- showPageStatus();
- top=1;
- return CLAIM;
- }
-
- //*************************************************************************
-
- void Find::nextHidden()
- {
- if (!nextWindow.isShowing())
- {
- nextHiddenTarget.destroy();
- nullEventTarget.destroy();
- if (view) view->clearHighlight();
- }
- }
-
- //*************************************************************************
-
- void Find::nullEvent()
- {
- int pageCount=view->getDocument().getPageCount();
- if (view==0 || (page<1 || page>pageCount))
- {
- nullEventTarget.destroy();
- return;
- }
-
- if (top) view->getDocument().getPage(page,&outDev,DrawOutputDevice::DPI,0);
-
- Unicode* unicode=new Unicode[searchString.size()];
- int i;
- if (!unicode)
- {
- nullEventTarget.destroy();
- return;
- }
- unsigned char*s=(unsigned char*)searchString.c_str();
- for (i=0;i<searchString.size();i++) unicode[i]=s[i];
-
- double xmax,ymax;
- if (outDev.findText(unicode,searchString.size(),
- top,1,&fromx,&fromy,&xmax,&ymax))
- {
- HighlightBBox box;
- box.xmin=fromx;
- box.ymin=outDev.getHeight()-ymax;
- box.xmax=xmax;
- box.ymax=outDev.getHeight()-fromy;
- fromx=xmax;
- fromy=ymax;
- top=0;
- nullEventTarget.destroy();
- nextStatus.setValue("Found");
- nextButton.fade(0);
- view->setHighlight(page,box);
- }
- else
- {
- page++;
- top=1;
- if (page>pageCount)
- {
- nextStatus.setValue("Not Found");
- }
- else
- {
- showPageStatus();
- }
- }
- delete [] unicode;
- }
-
- //*************************************************************************
-
- void Find::showPageStatus()
- {
- char buf[32];
- ostrstream out(buf,sizeof(buf));
- out << "Searching page: " << page;
- nextStatus.setValue(out.str());
- }
-
- //*************************************************************************
-
- Claim Find::findNext(GuiToolboxEvent&,const GuiIdBlock&)
- {
- if (view)
- {
- nullEventTarget(this,Find::nullEvent);
- nextButton.fade(1);
- }
- return CLAIM;
- }
-
- //*************************************************************************
-
- void find(DocView& view,bool ViewClosed)
- {
- static Find f;
- if (ViewClosed)
- f.viewClosed(view);
- else
- f.aboutToBeShown(view);
- }
-